programming4us
           
 
 
Applications Server

Microsoft Dynamics AX 2009 : Working with Forms - Using tree controls

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
12/30/2011 5:47:17 PM
Frequent users should notice that some of the Dynamics AX forms have an option to switch to a tree layout. In some cases, especially when there are parent-child relations among records, it is a much clearer way to show the whole hierarchy as compared to a flat list. For example, projects and their subprojects displayed in the Project Details form give a much better overview when switched to a tree layout.

This recipe will discuss the principles of how to build tree-based forms. As an example, we will use the Budget model form, which can be opened from General ledger | Setup | Budget | Budget model. This form contains a list of budget models and their submodels. Although the data is organized using a parent-child structure, currently this form does not have a hierarchy layout. The goal of this recipe is to correct that problem.

How to do it...

  1. 1. In AOT, create a new class called BudgetModelTree with the following code:

    class BudgetModelTree

    {
    FormTreeControl tree;
    BudgetModelId model;
    }
    void new(
    FormTreeControl _formTreeControl,
    BudgetModelId _budgetModelId)

    {;
    tree = _formTreeControl;
    model = _budgetModelId;
    }
    public static BudgetModelTree construct(
    FormTreeControl _formTreeControl,
    BudgetModelId _budgetModelId = '')

    {
    return new BudgetModelTree(
    _formTreeControl,
    _budgetModelId);
    }
    TreeItemIdx createNode(
    TreeItemIdx _parentIdx,
    BudgetModelId _modelId,
    RecId _recId)

    {
    TreeItemIdx itemIdx;
    BudgetModel modelSub;
    ;
    itemIdx = SysFormTreeControl::addTreeItem(
    tree,
    tree controltree controlusing_modelId,
    _parentIdx,
    _recId,
    0,
    true);
    if (model == _modelId)
    {
    tree.select(itemIdx);
    }
    while select modelSub
    where modelSub.ModelId == _modelId &&
    modelSub.Type == HeadingSub::SubModel
    {
    this.createNode(
    itemIdx,
    modelSub.SubModelId,
    modelSub.RecId);
    }
    return itemIdx;
    }
    void buildTree()

    {
    BudgetModel modelMain;
    BudgetModel modelSub;
    TreeItemIdx itemIdx;
    ;
    tree.deleteAll();
    tree.lock();
    tree controltree controlusingwhile select modelMain
    where modelMain.Type == HeadingSub::Heading
    notexists join modelSub
    where modelSub.SubModelId == modelMain.ModelId &&
    modelSub.Type == HeadingSub::SubModel
    {
    itemIdx = this.createNode(
    FormTreeAdd::Root,
    modelMain.ModelId,
    modelMain.RecId);
    SysFormTreeControl::expandTree(tree, itemIdx);
    }
    tree.unLock(true);
    }


  2. 2. Open the BudgetModel form in AOT, and create a new tab page:

    Property Value
    Name TabTree
    Caption Tree

  1. 3. Add a new Tree control to the new tab page:

    Property Value
    Name ModelTree
    Height Column height
    Width Column width

  1. 4. Add the following code to the bottom of the form's class declaration:

    BudgetModelTree budgetModelTree;
  2. 5. Override the form's init() with the following code:

    public void init()

    {;
    super();
    budgetModelTree = BudgetModelTree::construct(ModelTree);
    }
  3. 6. Override pageActivated() on the TabTree tab page with the following code:

    public void pageActivated()

    {;
    super();
    budgetModelTree.buildTree();
    }
  4. 7. In AOT the BudgetModel form should look like the following screenshot:

  1. 8. To test the tree control, open General ledger | Setup | Budget | Budget model, and select the Tree tab page. Notice how the ledger budget models are presented as a hierarchy:

How it works...

In order to separate the tree from the rest of the layout, we create a new tab page. Then, we add the actual tree control to the tab, which we use as a basis. Tree nodes are always generated from code. We also place all the tree-building logic into a separate class to make sure that it can be reused elsewhere, and the form itself does not get messy.

Besides the common new() and construct() methods, the class contains two methods, which actually generate the tree. The first method is createNode() and is used for creating a single budget model node or a whole branch. It is a recursive method, and it calls itself to generate the children of the current node. It accepts a parent node and a budget model as arguments. In this method, we create the node by calling the addTreeItem() method of the SysFormTreeControl class. The rest of the code loops through all submodels and creates subnodes (if there are any) for each of them.

Secondly, we create buildTree() where the whole tree is built. Before we actually start building it, we delete all nodes and lock the Tree control. Then, we add nodes by looping through all parent budget models and calling the previously mentioned createNode(). We call the expandTree() of the SysFormTreeControl class to show every parent budget model expanded. Once the hierarchy is ready, we unlock the Tree control.

Hierarchy generation might be time consuming, so we call it only when necessary, that is, when the tab page is actually opened. We override the tab page's and add a call to buildTree() there. Initially, to increase performance for bigger trees, only the first level of nodes has to be generated, and other nodes should be created only when the user clicks on the particular node. This could be achieved by placing the relevant code into the expanding() of the tree control in the form. Such an approach ensures that no time is spent on generating unused tree nodes. pageActivated()

There's more...

Besides hierarchical layout, tree controls also allow users to use drag-and-drop functionality. This makes daily operations much quicker and more effective. Let's modify the previous example to support drag-and-drop. We are going to allow users to move ledger budget submodels to different parents within the tree. In order to do that, we need to make some changes to the BudgetModelTree class and the BudgetModel form.

Add the following code to the BudgetModelTree class declaration:

TreeItemIdx dragItemIdx;
TreeItemIdx lastItemIdx;

Create the following additional methods in this class:

boolean canMove()

{
BudgetModel budgetModel;
RecId recId;
;
recId = tree.getItem(dragItemIdx).data();
select firstonly budgetModel
where budgetModel.RecId == recId;
return (budgetModel.Type == HeadingSub::SubModel);
}
void move(RecId _from, RecId _to)

{
BudgetModel modelFrom;
BudgetModel modelTo;
;
select firstonly modelTo
where modelTo.RecId == _to;
ttsbegin;
select firstonly forupdate modelFrom
where modelFrom.RecId == _from;
modelFrom.ModelId = modelTo.SubModelId;
if (modelFrom.validateWrite())
{
modelFrom.update();
tree controltree controldrag-and-drop, using}
ttscommit;
}
void stateDropHilite(TreeItemIdx _idx)

{
FormTreeItem item;
;
if (lastItemIdx)
{
item = tree.getItem(lastItemIdx);
item.stateDropHilited(false);
tree.setItem(item);
lastItemIdx = 0;
}
if (_idx)
{
item = tree.getItem(_idx);
item.stateDropHilited(true);
tree.setItem(item);
lastItemIdx = _idx;
}
}
int beginDrag(int _x, int _y)

{;
[dragItemIdx] = tree.hitTest(_x, _y);
return 1;
}
FormDrag dragOver(
FormControl _dragSource,
FormDrag _dragMode,
int _x,
int _y)

tree controltree controldrag-and-drop, using{
TreeItemIdx currItemIdx;
;
if (!this.canMove())
{
return FormDrag::None;
}
[currItemIdx] = tree.hitTest(_x, _y);
this.stateDropHilite(currItemIdx);
return FormDrag::Move;
}
void drop(
FormControl _dragSource,
FormDrag _dragMode,
int _x,
int _y)

{
TreeItemIdx currItemIdx;
;
if (!this.canMove())
{
return;
}
this.stateDropHilite(0);
[currItemIdx] = tree.hitTest(_x,_y);
if (!currItemIdx)
{
return;
}
this.move(
tree.getItem(dragItemIdx).data(),
tree.getItem(currItemIdx).data());
tree.moveItem(dragItemIdx, currItemIdx);
}




Locate the BudgetModel form in AOT, find its ModelTree control, and change the following property:

Property Value
DragDrop Manual

Also, override the following methods of the ModelTree control:

public int beginDrag(int _x, int _y)
{
return budgetModelTree.beginDrag(_x, _y);
}
FormDrag dragOver(
FormControl _dragSource,
FormDrag _dragMode,
int _x,
int _y)

{
return budgetModelTree.dragOver(
_dragSource,
_dragMode,
_x,
_y);
}
void drop(
FormControl _dragSource,
FormDrag _dragMode,
int _x,
int _y)

{;
budgetModelTree.drop(_dragSource, _dragMode, _x, _y);
}



Now when you open General ledger | Setup | Budget | Budget model, you should be able to move budget models within the tree with a mouse.

The main element in the latter modification is the DragDrop property of the tree control. It enables the drag-and-drop function, once we set its value to Manual. The next step is to override drag-and-drop events on the tree control. Tree controls could have a number of methods covering various drag-and-drop events. A good place to start investigating them is the Tutorial_Form_TreeControl class in the standard Dynamics AX application. In this example, we will cover only three of them:

  • beginDrag() is executed when dragging begins. Here, we normally store the number of the item that is being dragged for later processing.

  • dragOver() is executed once the dragged item is over another node. This method is responsible for highlighting nodes when the dragged item is over them. Its return value defines the mouse cursor icon once the item is being dragged.

  • drop() is executed when the mouse button is released, i.e. dragged item is dropped over some node. Here, we normally place the code that does actual data modifications.

In this example, all logic is stored in the BudgetModelTree class. Each of the mentioned form methods calls the relevant method in the class. This is to reduce the amount of code placed on the form and allow the code to be reused on multiple forms. We added the following methods to the class:

  • canMove() checks whether the currently selected node can be dragged. Although there might be more conditions, for this demonstration, we only disallow dragging of top nodes.

  • move() is where the actual movement of the budget model is performed, i.e. submodel is assigned with another parent.

  • stateDropHilite() is responsible for highlighting and removing highlight from relevant items. Using stateDropHilited(), we highlight the current item and we remove highlight from the previously highlighted one. This ensures that as we move the dragged item over the tree, items are highlighted once the dragged item is over them and the highlight is removed once dragged item leaves them. This method is called later from several places to make sure node highlighting works correctly.

  • beginDrag() saves the item currently being dragged into a variable.

  • dragOver() first checks if the currently selected item can be moved. If not, then it returns FormDrag::None, which changes the mouse cursor to the forbidden sign. Otherwise, the cursor is changed to an icon representing node movement. This method also calls stateDropHilite() to ensure correct node highlighting.

  • drop() also checks if the item being dropped can be moved. If yes, then it uses move() to update the data and moveItem() to visually change the node's place in the tree. It also calls stateDropHilite() to update tree node highlighting.

Other -----------------
- Active Directory Domain Services 2008 : Transfer the Schema Master Role
- Active Directory Domain Services 2008 : Identify Operations Master Role Holders
- Optimizing an Exchange Server 2007 Environment : Properly Sizing Exchange Server 2007
- Optimizing an Exchange Server 2007 Environment : Analyzing and Monitoring Core Elements
- SharePoint 2010 : Using Data Connection Libraries (part 1) - Connecting to Data Using Alternative Credentials & Configuring the Secure Store Service
- SharePoint 2010 : Using Data Connection Libraries (part 1) - Restricting Data Connection Types & Adding Connections to Data Connection Libraries
- SharePoint 2010 : Excel Services - Using the JavaScript Object Model
- Optimizing Exchange 2007 Servers & Monitoring Exchange Server 2007
- Optimizing an Exchange Server 2007 Environment : Analyzing Capacity and Performance
- Exchange Server 2010 : Planning Certificates for Autodiscover (part 2) - Deploying Exchange Certificates
- Exchange Server 2010 : Planning Certificates for Autodiscover (part 1) - The X.509 Certificate Standard
- Exchange Server 2010 Autodiscover : Autodiscover Concepts
- Active Directory 2008 : Proactive Directory Maintenance and Data Store Protection (part 5) - Protecting DCs as Virtual Machines
- Active Directory 2008 : Proactive Directory Maintenance and Data Store Protection (part 4) - Performing Proactive Restores
- Active Directory 2008 : Proactive Directory Maintenance and Data Store Protection (part 3) - Relying on Windows Server Backup to Protect the Directory
- Active Directory 2008 : Proactive Directory Maintenance and Data Store Protection (part 2) - Relying on Built-in Directory Protection Measures
- Active Directory 2008 : Proactive Directory Maintenance and Data Store Protection (part 1) - Twelve Categories of AD DS Administration
- BizTalk 2009 : The BizTalk Management Database
- BizTalk 2009 : Handling Failed Messages and Errors
- Microsoft Dynamics GP 2010 : Dynamics GP Utilities (part 3) - Additional steps
 
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us